<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./js/vue.js"></script>
</head>
<body>
  <h2>Vue 在更新 DOM 时是异步执行的。当数据发生变化，Vue将开启一个异步更新队列，视图需要等队列中所有数据变化完成之后，再统一进行更新，本质是一种优化策略，同步代码拿不到更新后的值。如果想要在修改数据后立刻得到更新后的DOM结构，可以使用Vue.nextTick()，Vue.nextTick()参数是一个箭头函数，可以写逻辑</h2>
  <h2>一、NextTick是什么</h2>
  <div>Vue 在更新 DOM 时是异步执行的。当数据发生变化，Vue将开启一个异步更新队列，视图需要等队列中所有数据变化完成之后，再统一进行更新</div>
  <div id="app"> {{ message }} </div>
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        message: '原始值'
      },
        // this.message = '修改后的值1'
        // this.message = '修改后的值2'
        // this.message = '修改后的值3'
        // console.log(vm.$el.textContent) // 原始值

// 这是因为message数据在发现变化的时候，vue并不会立刻去更新Dom，而是将修改数据的操作放在了一个异步操作队列中

// 如果我们一直修改相同数据，异步操作队列还会进行去重

// 等待同一事件循环中的所有数据变化完成之后，会将队列中的事件拿来进行处理，进行DOM的更新
    })
  </script>
  <h4>为什么要有nexttick</h4>
  <div>如果没有 nextTick 更新机制，那么 num 每次更新值都会触发视图更新(上面这段代码也就是会更新10万次视图)，有了nextTick机制，只需要更新一次，所以nextTick本质是一种优化策略</div>
  <h2>二、使用场景</h2>
  <div>如果想要在修改数据后立刻得到更新后的DOM结构，可以使用Vue.nextTick()</div>
  <br>
  <div>第一个参数为：回调函数（可以获取最近的DOM结构）</div>
  <br>
  <div>第二个参数为：执行函数上下文</div>
  <script>
    // 修改数据
    // vm.message = '修改后的值'
    // // DOM 还没有更新
    // console.log(vm.$el.textContent) // 原始的值
    // Vue.nextTick(function () {
    //   // DOM 更新了
    //   console.log(vm.$el.textContent) // 修改后的值
    // })

    // this.message = '修改后的值'
    // console.log(this.$el.textContent) // => '原始的值'
    // this.$nextTick(function () {
    //     console.log(this.$el.textContent) // => '修改后的值'
    // })

    // $nextTick() 会返回一个 Promise 对象，可以是用async/await完成相同作用的事情
    // this.message = '修改后的值'
    // console.log(this.$el.textContent) // => '原始的值'
    // await this.$nextTick()
    // console.log(this.$el.textContent) // => '修改后的值'
  </script>
  <br>
  <div>组件内使用 vm.$nextTick() 实例方法只需要通过this.$nextTick()，并且回调函数中的 this 将自动绑定到当前的 Vue 实例上</div>
  <h2>三、实现原理</h2>
  <h4>小结：</h4>
  <div>把回调函数放入callbacks等待执行</div>
  <br>
  <div>执行函数放到微任务或者宏任务中</div>
  <br>
  <div>事件循环到了微任务或者宏任务，执行函数依次执行callbacks中的回调</div>
</body>
</html>